package edu.hawaii.duedates;

import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * Defines a generic borrowed item and a generic method of printing its contents and due date.
 * 
 * @author Aric West
 * @author Daniel Tian
 */
public class BorrowedItem implements Comparable<BorrowedItem> {
  private final String itemName;
  private final Calendar dueDate;
  SimpleDateFormat dateFormat;

  /**
   * Constructor. Sets the values for the borrowed item.
   * 
   * @param fieldList a List of the item properties
   * @throws ParseException throws if the regex failed to find a match
   */
  public BorrowedItem(List<String> fieldList) throws ParseException {
    String formattedName = fieldList.get(0);
    String formattedDate = fieldList.get(1);
    String regex = "(0?[1-9]|1[012])[/.-](0?[1-9]|[12][0-9]|3[01])[/.-]((19|20)?\\d\\d)";
    dateFormat = new SimpleDateFormat("MM-dd-yy", Locale.US);
    
    formattedName = formattedName.replaceAll("/.*", "");
    formattedName = formattedName.trim(); // required to trim off trailing spaces
    
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(formattedDate);
    matcher.find();
    
    formattedDate = matcher.group();
    formattedDate = formattedDate.replaceAll("[./]", "-");
    
    this.itemName = formattedName;
    this.dueDate = Calendar.getInstance();
    this.dueDate.setTime(dateFormat.parse(formattedDate));
  }

  /**
   * Returns the name of the item.
   * @return the name of the item
   */
  public String getItemName() {
    return this.itemName;
  }
  
  /**
   * Returns the due date of the item.
   * @return the due date of the item
   */
  public Calendar getDueDate() {
    return this.dueDate;
  }
  
  /**
   * Returns the due date of the item as a string.
   * @return The due date of the item as a string.
   */
  public String getDueDateToString() {
    SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy", Locale.US);
    
    return df.format(this.dueDate.getTime());
  }
  
  /**
   * Compares this object's date to another object's date. Used for sorting.
   * @param o the object to compare this object to
   * @return the compareTo value
   */
  public int compareTo(BorrowedItem o) {
    return this.dueDate.compareTo(o.dueDate);
  }
  

  /**
   * Checks that a compared object is type BorrowedItem and that they have the same name, due date,
   * and lender. 
   * 
   * @param o object
   * @return boolean value
   */
  public boolean equals(Object o) {
    return o != null 
        && this.getClass().equals(o.getClass())
        && this.dueDate.equals( ((BorrowedItem) o).getDueDate() )
        && this.itemName.equals( ((BorrowedItem) o).getItemName() );
  }

  /**
   * Calculates a hashcode for this object.
   * 
   * @return A hash value based on the due date of the item.
   */
  public int hashCode() {
    int hash = 7;
    int dueDate = Integer.valueOf(this.getDueDateToString().replaceAll("-", ""));
    hash = hash + (dueDate * 31);
    return hash;
  }
}
